Artikel in Serie "Shells and related Scripting Languages"

sed ist auch eine Programmiersprache

Viele machen so etwas:

~$ grep abc | sed 's/x/y/'

Kürzer ist:

~$ sed '/abc/!d;s/x/y/'

Erklärung: Dieses sed-Programm besteht aus zwei durch „;“ voneinander getrennte Kommandos, „d“ und „s///„.

/abc/!“ ist eine Zeilenadressierung durch einen invertierten regulären Ausdruck, d.h. das folgende Kommando wird für alle Zeilen ausgeführt, auf die die ReEx nicht zutrifft. Das damit angewendete Kommando ist „d„, also „Zeile löschen“.

Das zweite Kommando, die Substitution „s///“ wird auf alle verbliebenen Zeilen ausgeführt.

Spass mit „awk“

Heute: wir wollen alle unvollständig deinstallierten Debian-Pakete vollständig löschen (das geht mit „dpkg --purge $Paketname„). Der erste Ansatz lautete:

dpkg -l | grep ^rc | awk '{print $2}' | xargs dpkg --purge

Dies lässt sich vereinfachen zu

dpkg -l | awk '/^rc/{print $2}' | xargs dpkg --purge

Damit ist schon mal das „grep“ gespart. Aber das „xargs“ braucht man auch nicht, sondern verwendet stattdessen die Kommando-Substitution mit „Back-Ticks“ („`„):

dpkg --purge `dpkg -l | awk '/^rc/{print $2}'`

Und das war’s. 🙂

 GNU find hat keine Option „-older“ …

… aber eine Funktion „-newer“. Die Funktion „-newer“ ist praktisch, um absolute Zeitangaben zum Aufspüren von Dateien zu verwenden. So würde

touch -d "2010/1/1" /tmp/test.newer
find . -type f -a -name 'core.*' -a -newer /tmp/test.newer

alle regulären Dateien mit „core.“ als Anfang des Dateinamens finden, die neuer sind als der 1. Januar 2010, 00:00 Uhr.

Jedoch gibt es (komischerweise) keine Option „-older“, d.h. man kann scheinbar nicht im gleichen Aufruf auch rückwärts eingrenzen, d.h. Dateien aus einem bestimmten absoluten Zeit-Intervall suchen.

Durch kurze Überlegung wird jedoch klar, dass man keine Option „-older“ braucht, weil es ja einen Negations-Operator gibt, der aus „-newer“ („neuer als“) „\! -newer“ (also „nicht neuer als“) macht. Also:

touch -d "2010/1/1" /tmp/test.newer
touch -d "2010/12/31" /tmp/test.older
find . -type f -a -name 'core.*' -a -newer /tmp/test.newer -a \! -newer /tmp/test.older

Und so findet man alle als „core.*“ benannten regulären Dateien aus dem Jahr 2010, wobei genau genommen der Zeitpunkt (timestamp) 1. Januar 2010, 0 Uhr, 0 Minuten und 0 Sekunden fehlt. Will man 100% Abdeckung, muss man die Referenz-Datei für „-newer“ wie folgt anlegen:

touch -d "2009/12/31 23:59:59" /tmp/test.newer

oder

touch -d "2010/01/01 - 1 second" /tmp/test.newer

Done.

Bourne to Bourne Again Shell Forward Compatibility

Introduction

In this article i try to find out, if Bourne Shell scripts are runnable in Bourne Again Shell without modification. If not, i advice on how to modify the code so that it runs on both Shells.

An interpreter for some variant of Bourne Shell is available as an executable /bin/sh on most Linux and UNIX systems. Writing Bourne Shell script has the possible advantage that such a script can work on all these systems with no changes to the code; be it Linux, AIX, FreeBSD, initramfs or a string passed to a C library call system(3), expressions such as

  • echo hello | wc
  • my_pid=$$

or

  • exit 1

would always work.

Recently, i used GNU Bourne Again Shell for scripting, and i wondered if all of my longstandingly Bourne Shell established practices were seamlessly portable. So i did some research, and in this article i highlight some code constructs i found that work in Bourne Shell and do not work as expected in Bourne Again Shell. Code currently interpreted by /bin/sh and containing such constructs must be reviewed if will be interpreted by /bin/bash.

As it stands, i will focus on reserved words and built-ins, brace expansion and pipeline subprocesses.

Protokoll meines Vortrags „Bourne Shell“ bei UUGRN e.V.

Ich hatte am 5.2.2021 die Ehre, einen Vortrag zum Thema „Bourne Shell“ auf der Veranstaltung FIXME der UNIX-User-Group Rhein Neckar, UUGRN e.V. halten zu dürfen. Hier ein Link zu den schriftlichen Aufzeichnungen dazu: https://wiki.uugrn.org/Bourne_Shell

Abseits des Vortrags, den ich auch mit Live-Demos usw. durchgeführt habe, hat die Mitschrift nur begrenzten Nutzen, aber die Linkliste am Ende der Seite ist recht eigenständig. Vor allem den Vortrag von Herrn Bourne aus dem Jahre 2015 empfehle ich für alle, die sich für den geschichtlichen Hintergrund interessieren.

Print XDG Desktop Definition for Application

For an application given by „application name“ or „executable name“, output the corresponding .desktop file, if any:

#!/bin/sh
IFS=":"
xdg_data_dirs=${XDG_DATA_DIRS:-/usr/local/share:/usr/share}
search=$1

for i in $xdg_data_dirs ; do
  a="$i/applications"

  [ -d $a ] && for d in "$a"/*.desktop ; do
    grep -q -e "^Name=.*$search" -e "^Exec=.*$search" "$d" && {
      echo "# $d:"
      grep -Ev '^(Comment|GenericName|Keywords|Name\[)' "$d"
    }
  done
done

To try this code out, save it to /usr/local/bin/xdg-desktop-search, make it executable and test it, for example, as follows:

xdg-desktop-search gnome-terminal

Find Files by Size given in Bytes

Some examples:

Find files in current directory that have a size of 400 bytes or more:

sfind -min 400

Find files in /etc that have a size of 50 kilobytes (1 kilobyte = 1024 bytes) or more:

sfind -dir /etc -min 50k

Find files in /var with size between 100 and 500 megabytes, suppress warnings, print sizes in human-readable format:

sfind -dir /var -min 100m -max 500m -quiet -human

Note: Yes, i know, Oracle distributes a tool that is also called „sfind“, but anyway …

Weiterlesen … »

Using sed or awk to ensure a specific last Line in a Text

Given a file containing bytes of text with lines separated by the newline character (\n), one of these lines can be said to be „the last line of the file“; it is a sequence of bytes occurring in the file, for which holds:

  • The sequence contains no newline character, and
  • the sequence is followed by at most one newline character and no other bytes.

The task at hand is, using shell utilities, to write a procedure that makes sure that a given file contains a last line that contains a desired sequence of text characters.

Weiterlesen … »